home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2007 December
/
PCWKCD1207B.iso
/
Blogowanie poza sfera
/
Flock 1.0 beta
/
flock-1.0RC3.en-US.win32.exe
/
flock
/
components
/
nsBookmarkTransactionManager.js
< prev
next >
Wrap
Text File
|
2007-10-18
|
22KB
|
535 lines
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is bookmark transaction code.
*
* The Initial Developer of the Original Code is
* Joey Minta <jminta@gmail.com>
*
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
function bookmarkTransactionManager() {
this.wrappedJSObject = this;
this.mTransactionManager = Components.classes["@mozilla.org/transactionmanager;1"]
.createInstance(Components.interfaces.nsITransactionManager);
this.mBatchCount = 0;
this.classInfo = {
getInterfaces: function (count) {
var ifaces = [
Components.interfaces.nsISupports,
Components.interfaces.nsIClassInfo
];
count.value = ifaces.length;
return ifaces;
},
getHelperForLanguage: function (language) {
return null;
},
contractID: "@mozilla.org/bookmarks/transactionManager;1",
classDescription: "Booksmarks Transaction Manager",
classID: Components.ID("{62d2f7fb-acd2-4876-aa2d-b607de9329ff}"),
implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
flags: 0
};
// Define our transactions
function bkmkTxn() {
this.item = null;
this.parent = null;
this.index = null;
this.removedProp = null;
};
bkmkTxn.prototype = {
BMDS: null,
QueryInterface: function bkmkTxnQI(iid) {
if (!iid.equals(Components.interfaces.nsITransaction) &&
!iid.equals(Components.interfaces.nsISupports))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
},
merge : function (aTxn) {return false},
getHelperForLanguage: function (aCount) {return null},
getInterfaces : function (aCount) {return null},
canCreateWrapper : function (aIID) {return "AllAccess"},
RDFCU: Components.classes["@mozilla.org/rdf/container-utils;1"]
.getService(Components.interfaces.nsIRDFContainerUtils),
getParents: function getParents(aResource) {
var parents = [];
var arcs = this.BMDS.ArcLabelsIn(aResource);
while (arcs && arcs.hasMoreElements()) {
var testresource = arcs.getNext();
if (testresource && testresource.QueryInterface) {
testresource.QueryInterface(Components.interfaces.nsIRDFResource);
if (this.RDFCU.IsOrdinalProperty(testresource)) {
var source = this.BMDS.GetSource(testresource, aResource, true)
.QueryInterface(Components.interfaces.nsIRDFResource);
if (parents.indexOf(source) == -1) {
//dump("CDC: found parent: "+source.Value+"\n");
parents.push(source);
}
}
}
}
//dump("CDC: found "+parents.length+" parents\n");
return parents;
},
mAssertProperties: function bkmkTxnAssertProps(aProps) {
if (!aProps) {
return;
}
//for each (var prop in aProps) { // Mozilla bug. Bruno
for (var i = 0; i < this.Properties.length; i++) {
var oldValue = this.BMDS.GetTarget(this.item, this.Properties[i], true);
// must check, if paste call after copy the oldvalue didn't remove.
if (!oldValue) {
var newValue = aProps[i];
if (newValue) {
this.BMDS.Assert(this.item,
this.Properties[i],
newValue, true);
}
} else {
this.removedProp[i] = oldValue;
}
}
//}
},
mUnassertProperties: function bkmkTxnUnassertProps(aProps) {
if (!aProps) {
return;
}
//for each (var prop in aProps) {// Mozilla bug. Bruno
for (var i = 0; i < this.Properties.length; i++) {
var oldValue = aProps[i];
if (oldValue) {
this.BMDS.Unassert(this.item, this.Properties[i], oldValue);
}
}
//}
}
};
bkmkTxn.prototype.RDFC =
Components.classes["@mozilla.org/rdf/container;1"]
.createInstance(Components.interfaces.nsIRDFContainer);
var rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"]
.getService(Components.interfaces.nsIRDFService);
bkmkTxn.prototype.BMDS = rdfService.GetDataSource("rdf:flock-favorites");
bkmkTxn.prototype.Properties =
[rdfService.GetResource("http://home.netscape.com/NC-rdf#Name"),
rdfService.GetResource("http://home.netscape.com/NC-rdf#URL"),
rdfService.GetResource("http://home.netscape.com/NC-rdf#ShortcutURL"),
rdfService.GetResource("http://home.netscape.com/NC-rdf#Description"),
rdfService.GetResource("http://home.netscape.com/NC-rdf#WebPanel"),
rdfService.GetResource("http://home.netscape.com/NC-rdf#FeedURL"),
rdfService.GetResource("http://home.netscape.com/NC-rdf#MicsumGenURI"),
rdfService.GetResource("http://home.netscape.com/NC-rdf#MicsumExpiration"),
rdfService.GetResource("http://home.netscape.com/NC-rdf#GeneratedTitle"),
rdfService.GetResource("http://home.netscape.com/NC-rdf#BookmarkAddDate"),
rdfService.GetResource("http://home.netscape.com/WEB-rdf#LastModifiedDate"),
rdfService.GetResource("http://home.netscape.com/WEB-rdf#LastVisitDate"),
rdfService.GetResource("http://home.netscape.com/WEB-rdf#LastCharset"),
rdfService.GetResource("http://flock.com/rdf#flockType"),
rdfService.GetResource("http://flock.com/rdf#isTransient"),
rdfService.GetResource("http://flock.com/rdf#isIndexable"),
rdfService.GetResource("http://flock.com/rdf#unseenItems"),
rdfService.GetResource("http://flock.com/rdf#count"),
rdfService.GetResource("http://flock.com/rdf#maxItems"),
rdfService.GetResource("http://flock.com/rdf#capItems"),
rdfService.GetResource("http://flock.com/rdf#hasUnseenItems"),
rdfService.GetResource("http://flock.com/rdf#isPollable"),
rdfService.GetResource("http://flock.com/rdf#refreshing"),
rdfService.GetResource("http://flock.com/rdf#shared"),
rdfService.GetResource("http://flock.com/rdf#favicon"),
rdfService.GetResource("http://flock.com/rdf#tags"),
rdfService.GetResource("http://flock.com/rdf#lastItemDate"),
rdfService.GetResource("http://flock.com/rdf#lastRefresh"),
rdfService.GetResource("http://flock.com/rdf#lastQuery"),
rdfService.GetResource("http://flock.com/rdf#refreshInterval"),
rdfService.GetResource("http://flock.com/rdf#datevalue"),
rdfService.GetResource("http://flock.com/rdf#CoopType"),
rdfService.GetResource("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")];
function bkmkInsertTxn(aAction) {
this.type = "insert";
// move container declaration to here so it can be recognized if
// undoTransaction is call after the BM manager is close and reopen.
this.container = Components.classes["@mozilla.org/rdf/container;1"]
.createInstance(Components.interfaces.nsIRDFContainer);
}
bkmkInsertTxn.prototype = {
__proto__: bkmkTxn.prototype,
isTransient: false,
doTransaction: function bkmkInsertDoTxn() {
this.RDFC.Init(this.BMDS, this.parent);
// if the index is -1, we use appendElement, and then update the
// index so that undoTransaction can still function
if (this.index == -1) {
this.RDFC.AppendElement(this.item);
this.index = this.RDFC.GetCount();
} else {
/*XXX- broken insert code, see bug 264571
try {
this.RDFC.InsertElementAt(this.item, this.index, true);
} catch (e if e.result == Components.results.NS_ERROR_ILLEGAL_VALUE) {
// if this failed, then we assume that we really want to append,
// because things are out of whack until we renumber.
this.RDFC.AppendElement(this.item);
// and then fix up the index so undo works
this.index = this.RDFC.GetCount();
}
*/
this.RDFC.InsertElementAt(this.item, this.index, true);
}
// insert back all the properties
this.mAssertProperties(this.removedProp);
},
undoTransaction: function bkmkInsertUndoTxn() {
// XXXvarga Can't use |RDFC| here because it's being "reused" elsewhere.
this.container.Init(this.BMDS, this.parent);
// remove all properties befor we remove the element so
// nsLocalSearchService doesn't return deleted element in Search
this.mUnassertProperties(this.removedProp);
this.container.RemoveElementAt(this.index, true);
},
redoTransaction: function bkmkInsertRedoTxn() {
this.doTransaction();
}
};
function bkmkRemoveTxn() {
this.type = "remove";
}
bkmkRemoveTxn.prototype = {
__proto__: bkmkTxn.prototype,
isTransient: false,
doTransaction: function bkmkRemoveDoTxn() {
this.RDFC.Init(this.BMDS, this.parent);
// remove all properties befor we remove the element so
// nsLocalSearchService doesn't return deleted element in Search
this.mUnassertProperties(this.removedProp);
this.RDFC.RemoveElementAt(this.index, false);
},
undoTransaction: function bkmkRemoveUndoTxn() {
this.RDFC.Init(this.BMDS, this.parent);
this.RDFC.InsertElementAt(this.item, this.index, false);
// insert back all the properties
this.mAssertProperties(this.removedProp);
},
redoTransaction: function () {
this.doTransaction();
}
}
function bkmkRemoveAllTxn() {
this.type = "removeAll";
}
bkmkRemoveAllTxn.prototype = {
__proto__: bkmkTxn.prototype,
isTransient: false,
childContainer:
Components.classes["@mozilla.org/rdf/container;1"]
.createInstance(Components.interfaces.nsIRDFContainer),
doTransaction: function bkmkRemoveDoTxn() {
this.item.QueryInterface(Components.interfaces.nsIRDFResource);
//dump("CDC: bkmkRemoveAllDoTxn('"+this.item.Value+"')\n");
checkTopSitesRequirement = function checkTopSitesRequirement(aParents) {
for(var i=0;i<aParents.length;i++) {
var parent = aParents[i];
if(parent.Value == "urn:flock:topsites") {
return true;
}
}
return false;
};
// When 'deleting' a bookmark item, we only want to REALLY delete
// it if it has EXACTLY one parent
if ( (this.getParents(this.item).length == 1)
|| (this.getParents(this.item).length == 2 && checkTopSitesRequirement(this.getParents(this.item)))
) {
// First, recursively delete any children of this one...
if (this.RDFCU.IsContainer(this.BMDS, this.item)) {
this.childContainer.Init(this.BMDS, this.item);
var children = this.childContainer.GetElements();
this.mSubTransactions = [];
while (children && children.hasMoreElements()) {
var child = children.getNext();
var txn = new bkmkRemoveAllTxn();
txn.item = child;
txn.parent = this.item;
txn.index = this.childContainer.IndexOf(child);
txn.action = this.action;
txn.removedProp = [];
for (var i = 0; i < this.Properties.length; i++) {
txn.removedProp[i] = this.BMDS.GetTarget(child, this.Properties[i], true);
}
txn.wrappedJSObject = txn;
this.mSubTransactions.push(txn);
}
for (var i = 0; i < this.mSubTransactions.length; i++) {
this.mSubTransactions[i].doTransaction();
}
}
// Remove all properties before we remove the element so
// nsLocalSearchService doesn't return deleted element in Search
this.mUnassertProperties(this.removedProp);
}
// Remove the item from its parent (this always gets done,
// regardless of how many other parents there might be)
//dump("CDC: bkmkRemoveAllDoTxn "+this.index+"\n");
try {
this.RDFC.Init(this.BMDS, this.parent);
//If index == -1 then we don't have an index to remove
// this can happen when bookmark is created and then removed, it might not have an index
if(this.index > -1)
this.RDFC.RemoveElementAt(this.index, false);
}catch(e)
{
}
},
undoTransaction: function bkmkRemoveUndoTxn() {
// Reinstate the arc to the main parent
this.RDFC.Init(this.BMDS, this.parent);
this.RDFC.InsertElementAt(this.item, this.index, false);
if (this.getParents(this.item).length == 1) {
// insert back all the properties
this.mAssertProperties(this.removedProp);
// Undo all the sub-transactions (contained bookmarks)
if (this.mSubTransactions) {
for (var i = this.mSubTransactions.length - 1; i >= 0; i--) {
this.mSubTransactions[i].undoTransaction();
this.mSubTransactions[i] = undefined;
}
this.mSubTransactions = undefined;
}
}
},
redoTransaction: function () {
this.doTransaction();
}
}
function bkmkImportTxn(aAction) {
this.type = "import";
this.action = aAction;
}
bkmkImportTxn.prototype = {
__proto__: bkmkTxn.prototype,
isTransient: false,
doTransaction: function bkmkImportDoTxn() {},
undoTransaction: function mkmkImportUndoTxn() {
this.RDFC.Init(this.BMDS, this.parent);
this.RDFC.RemoveElementAt(this.index, true);
},
redoTransaction: function bkmkImportredoTxn() {
this.RDFC.Init(this.BMDS, this.parent);
this.RDFC.InsertElementAt(this.item, this.index, true);
}
};
this.BookmarkRemoveTransaction = bkmkRemoveTxn;
this.BookmarkRemoveAllTransaction = bkmkRemoveAllTxn;
this.BookmarkInsertTransaction = bkmkInsertTxn;
this.BookmarkImportTransaction = bkmkImportTxn;
}
bookmarkTransactionManager.prototype.QueryInterface = function bkTxnMgrQI(aIID) {
if (aIID.equals(Components.interfaces.nsISupports) ||
aIID.equals(Components.interfaces.nsIBookmarkTransactionManager)) {
return this;
}
if (aIID.equals(Components.interfaces.nsIClassInfo)) {
return this.classInfo;
}
throw NS_ERROR_NO_INTERFACE;
}
bookmarkTransactionManager.prototype.createAndCommitTxn =
function bkmkTxnMgrCandC(aType, aAction, aItem, aIndex, aParent, aPropCount, aRemovedProps) {
//dump("CDC: createAndCommitTxn(aType='"+aType+"', aAction='"+aAction+"', aIndex="+aIndex+")\n");
var txn;
var nsIBookmarkTransactionManager = Components.interfaces.nsIBookmarkTransactionManager;
switch (aType) {
case nsIBookmarkTransactionManager.IMPORT:
txn = new this.BookmarkImportTransaction(aAction);
break;
case nsIBookmarkTransactionManager.INSERT:
txn = new this.BookmarkInsertTransaction(aAction);
break;
case nsIBookmarkTransactionManager.REMOVE:
if (aAction == "move") {
txn = new this.BookmarkRemoveTransaction(aAction);
} else {
txn = new this.BookmarkRemoveAllTransaction(aAction);
}
break;
default:
Components.utils.reportError("Unknown bookmark transaction type:"+aType);
throw NS_ERROR_FAILURE;
}
txn.item = aItem;
txn.parent = aParent;
txn.index = aIndex;
txn.removedProp = aRemovedProps;
txn.action = aAction;
txn.wrappedJSObject = txn;
this.mTransactionManager.doTransaction(txn);
//dump("CDC: end createAndCommitTxn(aType='"+aType+"', aAction='"+aAction+"', aIndex="+aIndex+")\n");
}
bookmarkTransactionManager.prototype.startBatch = function bkmkTxnMgrUndo() {
if (this.mBatchCount == 0) {
this.mTransactionManager.beginBatch();
}
this.mBatchCount++;
}
bookmarkTransactionManager.prototype.endBatch = function bkmkTxnMgrUndo() {
this.mBatchCount--;
if (this.mBatchCount == 0) {
this.mTransactionManager.endBatch();
}
}
bookmarkTransactionManager.prototype.undo = function bkmkTxnMgrUndo() {
this.mTransactionManager.undoTransaction();
}
bookmarkTransactionManager.prototype.redo = function bkmkTxnMgrRedo() {
this.mTransactionManager.redoTransaction();
}
bookmarkTransactionManager.prototype.canUndo = function bkmkTxnMgrCanUndo() {
return this.mTransactionManager.numberOfUndoItems > 0;
}
bookmarkTransactionManager.prototype.canRedo = function bkmkTxnMgrCanRedo() {
return this.mTransactionManager.numberOfRedoItems > 0;
}
bookmarkTransactionManager.prototype.__defineGetter__("transactionManager",
function bkmkTxnMgrGetter() { return this.mTransactionManager; });
/****
**** module registration
****/
const kFactory = {
createInstance: function (outer, iid) {
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return (new bookmarkTransactionManager()).QueryInterface(iid);
}
};
var bkmkTxnMgrModule = {
mCID: Components.ID("{8be133d0-681d-4f0b-972b-6a68e41afb62}"),
mContractID: "@mozilla.org/bookmarks/transactionmanager;1",
registerSelf: function (compMgr, fileSpec, location, type) {
compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
compMgr.registerFactoryLocation(this.mCID,
"Bookmark Transaction Manager",
this.mContractID,
fileSpec,
location,
type);
},
getClassObject: function (compMgr, cid, iid) {
if (!cid.equals(this.mCID))
throw Components.results.NS_ERROR_NO_INTERFACE;
if (!iid.equals(Components.interfaces.nsIFactory))
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
return kFactory;
},
canUnload: function(compMgr) {
return true;
}
};
function NSGetModule(compMgr, fileSpec) {
return bkmkTxnMgrModule;
}